﻿using Sustainalytics.Auth.Claims;
using Sustainalytics.BusinessResearchProductStates.Entities.ResearchState;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using CorporateData = Sustainalytics.ClientDW.Entities.CorporateData;

namespace Sustainalytics.Companies.Service.Models
{

    public class CorporateDataDto
    {
        public Guid Id { get; set; }
        public string CompanyName { get; set; }
        public string CompanyNameUrlFriendly { get; set; }
        public string Ticker { get; set; }
        public string ExchangeCode { get; set; }
        public string TickerAndExchange { get; set; }
        public string Country { get; set; }
        public string PeerGroup { get; set; }

        #region added from Extended

        public string SubPeerGroup { get; set; }

        public string Address { get; set; }
        public int? TotalEmployees { get; set; }
        public string CompanyPhone { get; set; }
        public string Website { get; set; }
        public string BusinessDescription { get; set; }


        public bool IsCoverageEntity { get; set; }
        public string CompanyResearched { get; set; }
        public Guid? CoverageId { get; set; }

        #endregion

        public ResearchState ComprehensiveEsgResearchState { get; set; }
        public ResearchState CoreEsgResearchState { get; set; }
        public ResearchState RiskRatingResearchState { get; set; }
        public ResearchState CoreRiskResearchState { get; set; }
        public ResearchState SustainableProductsResearchState { get; set; }
        public ResearchState ProductInvolvementResearchState { get; set; }
        public ResearchState GccsResearchState { get; set; }
        public ResearchState CorporateGovernanceResearchState { get; set; }
        public ResearchState ControversyResearchState { get; set; }
        public bool HasEsgAccountFeature { get; set; }
        public bool HasSPAccountFeature { get; set; }
        public bool HasRiskRatingAccountFeature { get; set; }
        public bool HasPIAccountFeature { get; set; }
        public bool HasControversiesAccountFeature { get; set; }
        public bool HasGovernanceAccountFeature { get; set; }
        public bool HasGCCSAccountFeature { get; set; }

        public bool IsEnabled { get; private set; }
        public bool HasProductInvolvementIndicators { get; set; }
        public bool HasSustainableProductIndicators { get; set; }

        public CorporateDataDto LoadLessCorporateData(
            CorporateData data, 
            List<int> accountUniverses, 
            bool hasProductInvolvementIndicators = false)
        {
            Id = data.Id;
            CompanyName = data.CompanyName;
            CompanyNameUrlFriendly = data.CompanyNameUrlFriendly;
            ExchangeCode = data.MainExchange;
            Country = data.Country;

            //In Admin all companies are available
            IsEnabled = (data.UniverseIds != null && data.UniverseIds.Any(u => accountUniverses.Contains(u)));
            HasProductInvolvementIndicators = hasProductInvolvementIndicators;

            SetResearchStates(data);
            SetAccountFeatures(data);

            PeerGroup = data.PeerGroup;
            Ticker = data.MainTicker;
            TickerAndExchange = GetExchangeTicker(Ticker, ExchangeCode);

            return this;
        }

        public CorporateDataDto LoadFrom(
            CorporateData data, 
            List<int> accountUniverses, 
            bool hasProductInvolvementIndicators = false,
            bool hasSustainableProductIndicators = false)
        {
            Id = data.Id;
            CompanyName = data.CompanyName;
            CompanyNameUrlFriendly = data.CompanyNameUrlFriendly;
            Country = data.Country;
            SubPeerGroup = data.SubPeerGroup;

            IsEnabled = (data.UniverseIds != null && data.UniverseIds.Any(u => accountUniverses.Contains(u)));
            HasProductInvolvementIndicators = hasProductInvolvementIndicators;


            Ticker = data.MainTicker;
            ExchangeCode = data.MainExchange;

            TickerAndExchange = GetExchangeTicker(Ticker, ExchangeCode);

            SetResearchStates(data);
            SetAccountFeatures(data);

            return this;
        }

        public CorporateDataDto LoadFullCompany(
            CorporateData data, 
            List<int> accountUniverses, 
            bool hasProductInvolvementIndicators = false,
            bool hasSustainableProductIndicators = false)
        {
            Id = data.Id;
            CompanyName = data.CompanyName;
            CompanyNameUrlFriendly = data.CompanyNameUrlFriendly;
            PeerGroup = data.PeerGroup;
            SubPeerGroup = data.SubPeerGroup;
            Address = data.Address;
            TotalEmployees = data.TotalEmployees;
            CompanyPhone = data.CompanyPhone;
            Website = data.Website;
            BusinessDescription = data.BusinessDescription;
            ExchangeCode = data.MainExchange;
            Ticker = data.MainTicker;
            Country = data.Country;

            IsEnabled = (data.UniverseIds != null && data.UniverseIds.Any(u => accountUniverses.Contains(u)));
            HasProductInvolvementIndicators = hasProductInvolvementIndicators;
            HasSustainableProductIndicators = hasSustainableProductIndicators;

            if (!string.IsNullOrEmpty(Country) && !string.IsNullOrEmpty(Address) && !Address.Equals("NA"))
            {
                Address = $"{Address},{Country}";
            }
            TickerAndExchange = GetExchangeTicker(Ticker, ExchangeCode);

            SetResearchStates(data);
            SetAccountFeatures(data);
            return this;
        }

        public CorporateDataDto LoadToAdmin(CorporateData data)
        {
            Id = data.Id;
            CompanyName = data.CompanyName;
            CompanyNameUrlFriendly = data.CompanyNameUrlFriendly;
            Country = data.Country;

            IsEnabled = true; //In Admin all companies are available

            Ticker = data.MainTicker;
            ExchangeCode = data.MainExchange;
            TickerAndExchange = GetExchangeTicker(Ticker, ExchangeCode);

            return this;
        }

        private void SetAccountFeatures(CorporateData data)
        {
            var univEsg = ClaimsPrincipal.Current.Claims.GetUniverseIds(AccountFeature.EsgRatingsOnlineReport);
            var univRiskRating = ClaimsPrincipal.Current.Claims.GetUniverseIds(AccountFeature.RiskRatingsResearch);
            var univPi = ClaimsPrincipal.Current.Claims.GetUniverseIds(AccountFeature.ProductInvolvement);
            var univSP = ClaimsPrincipal.Current.Claims.GetUniverseIds(AccountFeature.SustainableProducts);
            var univControversies = ClaimsPrincipal.Current.Claims.GetUniverseIds(AccountFeature.Controversies);
            var univGovernance = ClaimsPrincipal.Current.Claims.GetUniverseIds(AccountFeature.Governance);
            var univGccsNc = ClaimsPrincipal.Current.Claims.GetUniverseIds(AccountFeature.GlobalCompactNonCompliant);
            var univGccsWl = ClaimsPrincipal.Current.Claims.GetUniverseIds(AccountFeature.GlobalCompactWatchlist);
            var univGccsNcWl = ClaimsPrincipal.Current.Claims.GetUniverseIds(AccountFeature.GlobalCompactWatchlistAndNonCompliant);

            HasEsgAccountFeature = data.UniverseIds != null && data.UniverseIds.Any(univEsg.Contains);
            HasRiskRatingAccountFeature = data.UniverseIds != null && data.UniverseIds.Any(univRiskRating.Contains);
            HasControversiesAccountFeature = data.UniverseIds != null && data.UniverseIds.Any(univControversies.Contains);
            HasGovernanceAccountFeature = data.UniverseIds != null && data.UniverseIds.Any(univGovernance.Contains);
            HasPIAccountFeature = data.UniverseIds != null && data.UniverseIds.Any(univPi.Contains);
            HasSPAccountFeature = data.UniverseIds != null && data.UniverseIds.Any(univSP.Contains);
            HasGCCSAccountFeature = data.UniverseIds != null && (data.UniverseIds.Any(univGccsNc.Contains) ||
                                                                    data.UniverseIds.Any(univGccsWl.Contains) ||
                                                                    data.UniverseIds.Any(univGccsNcWl.Contains));

        }

        private void SetResearchStates(CorporateData data)
        {
            ComprehensiveEsgResearchState = data.ComprehensiveEsgResearchState.ResearchState;
            CoreEsgResearchState = data.CoreEsgResearchState.ResearchState;
            SustainableProductsResearchState = data.SolutionsResearchState.ResearchState;
            RiskRatingResearchState = data.RiskRatingResearchState.ResearchState;
            CoreRiskResearchState = data.CoreRiskResearchState.ResearchState;
            ProductInvolvementResearchState = data.ProductInvolvementResearchState.ResearchState;
            SustainableProductsResearchState = data.SolutionsResearchState.ResearchState;
            GccsResearchState = data.GccsResearchState.ResearchState;
            CorporateGovernanceResearchState = data.CorporateGovernanceResearchState.ResearchState;
            ControversyResearchState = data.ControversyResearchState.ResearchState;
        }

        private string GetExchangeTicker(string ticker, string exchange)
        {
            return (!string.IsNullOrEmpty(ticker) && !string.IsNullOrEmpty(exchange))
               ? $"{ExchangeCode}:{Ticker}"
               : null;
        }
    }
}
